import deviceAPI from "@/api/device/device";
import deviceCalendarAPI from "@/api/device/calendar";
import { codeByType } from "@/views/device/common";
import { MultipleValueChart, DoubleGroupChart } from "@/views/components/chart";
import { today } from "@/views/components/utils";

const todaySecond = function () {
  const now = new Date();
  const date = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  return (now.getTime() - date.getTime()) / 1000;
};

export const valueFormat = {
  workPercent: {
    name: "chart.UsePercent",
    unit: "chart.Percent",
  },
  onlinePercent: {
    name: "chart.OnlinePercent",
    unit: "chart.Percent",
  },
  online: {
    name: "chart.OnlineSecond",
    unit: "chart.Second",
  },
  work: {
    name: "chart.WorkSecond",
    unit: "chart.Second",
  },
  energy: {
    name: "chart.Energy",
    unit: "chart.EnergyUnit",
  },
  totalCount: {
    name: "chart.Count",
    unit: "chart.Number",
  },
  onlineCount: {
    name: "chart.OnlineCount",
    unit: "chart.DayTime",
  },
  workCount: {
    name: "chart.WorkCount",
    unit: "chart.DayTime",
  },
  offlineCount: {
    name: "chart.offlineCount",
    unit: "chart.Count",
  },
};

const parseGroupStatus = function (query) {
  const { groupDept, groupType, groupDate } = query;
  const dates = [1, 2, 3];
  if (groupDept === true && groupType === true) {
    return 2;
  }
  if (groupDept === true && dates.includes(groupDate)) {
    return 3;
  }
  if (dates.includes(groupDate) && groupType === true) {
    return 4;
  }
  if (groupDept === true) {
    return 0;
  }
  if (groupType === true) {
    return 1;
  }
  if (dates.includes(groupDate)) {
    return 5;
  }
};

const oneDaySecond = 24 * 60 * 60;

export const DeviceCountMap = {
  name: "DeviceCountMap",
  data() {
    return {
      devices: [],
      total: 0,
      deptMap: {},
      typeMap: {},
      deptTypeMap: {},
    };
  },
  created() {
    this.loadDevice();
  },
  methods: {
    loadDevice() {
      const vm = this;
      deviceAPI.list().then((res) => {
        vm.setDevices(res.data);
      });
    },
    afterCountDevice() {
      console.warn("DeviceCountMap.afterCountDevice have not rewrite");
    },
    setDevices(list) {
      const typeMap = {};
      const deptMap = {};
      const deptTypeMap = {};
      for (var i = 0; i < list.length; i++) {
        const { deptId, type } = list[i];
        if (typeMap[type] === undefined) {
          typeMap[type] = 0;
        }
        typeMap[type] += 1;
        if (deptMap[deptId] === undefined) {
          deptMap[deptId] = 0;
        }
        deptMap[deptId] += 1;
        const key = `${deptId}_${type}`;
        if (deptTypeMap[key] === undefined) {
          deptTypeMap[key] = 0;
        }
        deptTypeMap[key] += 1;
      }
      this.typeMap = Object.assign({}, typeMap);
      this.deptMap = Object.assign({}, deptMap);
      this.deptTypeMap = Object.assign({}, deptTypeMap);
      this.devices = [].concat(list);
      this.total = list.length;
      this.afterCountDevice();
    },
  },
};
const DaySecond = 60 * 60 * 24;
const MonthSecond = DaySecond * 30;
const YearSecond = DaySecond * 256;

export const CalendarData = {
  name: "CalendarData",
  data() {
    const vm = this;
    return {
      queryDateType: "month",
      dateConfig: {
        year: {
          type: "year",
          label: vm.$t("Year"),
          format: "yyyy",
          second: YearSecond,
        },
        month: {
          type: "month",
          label: vm.$t("Month"),
          format: "yyyy-MM",
          second: MonthSecond,
        },
        date: {
          type: "date",
          label: vm.$t("Date"),
          format: "yyyy-MM-dd",
          second: DaySecond,
        },
      },
      queryTime: { type: "month", label: vm.$t("Month"), format: "yyyy-MM" },
      fullSecond: DaySecond,
      queryParams: {
        date: null,
        groupDept: false,
        groupType: false,
        groupDate: 3,
      },
      list: [],
    };
  },
  created() {
    const { dateConfig, queryDateType, queryParams } = this;
    this.qeuryTime = dateConfig[queryDateType];
    const { format, second } = this.qeuryTime;
    this.fullSecond = second;
    queryParams.date = today(format);
  },
  methods: {
    beforeQuery() {},
    afterLoaderData() {},
    queryData() {
      const vm = this;
      this.beforeQuery();
      deviceCalendarAPI.analysis(this.queryParams).then((res) => {
        vm.list = res.data;
        vm.afterLoaderData();
      });
    },
  },
};

export const CalendarChart = {
  name: "CalendarChart",
  mixins: [CalendarData],
  data() {
    return {
      isTranslated: false,
      valueFormat,
      // legalValues: [
      //   "totalCount",
      //   "onlineCount",
      //   "workCount",
      //   "online",
      //   "work",
      //   "energy",
      // ],
      // legalGroups: ["department", "type", "date"],
    };
  },
  created() {
    this.queryData();
  },
  methods: {
    afterCountDevice() {
      this.isTranslated = false;
      this.setGroupCount();
      this.translate();
    },
    beforeQuery() {
      this.setQueryParams();
      this.setGroupCount();
    },
    afterLoaderData() {
      this.isTranslated = false;
      this.translate();
    },
    changeDate(v) {
      if (today() === v) {
        this.fullSecond = todaySecond();
      } else {
        this.fullSecond = oneDaySecond;
      }
      this.queryData();
    },
    setQueryParams() {
      const { queryParams, groupKeys } = this;
      queryParams.groupDept = groupKeys.includes("department");
      queryParams.groupType = groupKeys.includes("type");
      // queryParams.groupDate = 0;
    },
    setGroupCount() {
      console.warn("CalendarChart.setGroupCount have not rewrite");
    },
    getGroupCount() {
      console.warn("CalendarChart.getGroupCount have not rewrite");
    },
    getGroupCountItemKey(item) {
      const { groupDept, groupType } = this.queryParams;
      const { type, deptId } = item;
      if (groupDept === true && groupType === true) {
        return `${deptId}_${type}`;
      } else if (groupDept === true) {
        return `${deptId}`;
      } else if (groupType === true) {
        return `${type}`;
      }
      return null;
    },
    translate() {
      const groupCount = this.getGroupCount();
      if (
        this.isTranslated ||
        (Object.keys(groupCount).length === 0 && this.total === 0)
      ) {
        return;
      }
      this.list = this.list.map(this.translateItem);
      this.isTranslated = true;
      this.updateChart();
    },
    autoTranslateItem(item) {
      const groupCount = this.getGroupCount();
      const { fullSecond, total } = this;
      const key = this.getGroupCountItemKey(item);
      const count = (key !== null ? groupCount[key] : total) || 0;
      item.online = item.online || 0;
      item.work = item.work || 0;
      item.type = this.$t("dictionary." + codeByType(item.type));
      item.totalCount = count;
      if (count === 0) {
        item.onlinePercent = 0;
        item.workPercent = 0;
        return item;
      }
      const totalSecond = count * fullSecond;
      item.onlinePercent = ((item.online / totalSecond) * 100).toFixed(2);
      item.workPercent = ((item.work / totalSecond) * 100).toFixed(2);
      return item;
    },
    translateItem(item) {
      return this.autoTranslateItem(item);
    },
  },
};

export const FreeCalendarChart = {
  name: "FreeCalendarChart",
  mixins: [CalendarChart, DeviceCountMap],
  data() {
    return {
      groupCount: {},
    };
  },
  methods: {
    getGroupCount() {
      return this.groupCount;
    },
    setGroupCount() {
      const { deptTypeMap, deptMap, typeMap } = this;
      const { groupDept, groupType } = this.queryParams;
      if (groupDept === true && groupType === true) {
        this.groupCount = Object.assign({}, deptTypeMap);
      } else if (groupDept === true) {
        this.groupCount = Object.assign({}, deptMap);
      } else if (groupType === true) {
        this.groupCount = Object.assign({}, typeMap);
      }
    },
  },
};

export const DependCalendarChart = {
  name: "DependCalendarChart",
  mixins: [CalendarChart],
  props: {
    total: {
      required: true,
      type: Number,
    },
    groupCount: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  watch: {
    groupCount() {
      this.isTranslated = false;
      this.translate();
    },
  },
  methods: {
    getGroupCount() {
      return this.groupCount;
    },
    setGroupCount() {},
  },
};

export const ComponentCalendarChart = {
  name: "TodayComponentTranslater",
  mixins: [DependCalendarChart],
  data() {
    return {
      isTranslated: false,
      valueFormat,
    };
  },
  created() {
    this.queryParams.date = today();
  },
  methods: {},
};

export const TodayDoubleGroupChart = {
  name: "TodayDoubleGroupChart",
  mixins: [DoubleGroupChart, ComponentCalendarChart],
};
export const TodayMultiValueChart = {
  name: "TodayMultiValueChart",
  mixins: [MultipleValueChart, ComponentCalendarChart],
};

export default FreeCalendarChart;
